﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Globalization;

namespace ComputationVisualizer
{
    /// <summary>
    /// Interaction logic for PlayerControl.xaml
    /// </summary>
    public partial class PlayerControl : UserControl
    {
        private PlayerModel playerModel=new PlayerModel();
        private NumberFormatInfo _numberFormat = new CultureInfo("en-US", false).NumberFormat;
		
		private Rectangle rectangleCont;
		private object pathCont;

        public PlayerControl()
        {
            InitializeComponent();
			rectangleCont = new Rectangle();
			rectangleCont.Width = 20;
			rectangleCont.Height = 20;
            rectangleCont.Fill = Brushes.Black;
			pathCont = playStopBtn.Content;
        }

        public PlayerModel PlayerModel
        {
            get { return playerModel; }
            set {
                playerModel.SpeedNumberUpdated -= playerModel_SpeedNumberUpdated;
                playerModel.FrameNumberUpdated -= playerModel_FrameNumberUpdated;
                playerModel.StartedPlaying -= playerModel_StartedPlaying;
                playerModel.StoppedPlaying -= playerModel_StoppedPlaying;
                playerModel = value;
                SetEventHandlers();
            }
        }

        public void SetDataSource(Func<double, BitmapSource> bitmapProvider, double count)
        {
            playerModel.BitmapProvider= bitmapProvider;
            playerModel.FramesCount = count;
        }

        public double FrameNumber
        {
            get { return playerModel.CurrentTimeValue; }
            set { playerModel.CurrentTimeValue = value; }
        }

        public double FrameSpeed
        {
            get { return playerModel.Speed; }
            set { playerModel.Speed = value; }
        }

        #region UI Inputs
        private void framesSpeedScrollBar_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            playerModel.Speed = framesSpeedScrollBar.Value;
        }

        private void framesTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            double buffer = 0;
            if (Double.TryParse(framesTextBox.Text, NumberStyles.None, _numberFormat, out buffer))
                playerModel.Speed = buffer;
        }

        private void positionSlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            FrameNumber = positionSlider.Value;
        }

        private void nextCadreBtn_Click(object sender, RoutedEventArgs e)
        {
            FrameNumber += 1;
        }

        private void prevCadreBtn_Click(object sender, RoutedEventArgs e)
        {
            FrameNumber -= 1;
        }

        private void playStopBtn_Checked(object sender, RoutedEventArgs e)
        {
            playerModel.StartPlaying();
        }

        private void playStopBtn_Unchecked(object sender, RoutedEventArgs e)
        {
            playerModel.StopPlaying();
        }

        #endregion

        #region UI_Updates

        void playerModel_FrameNumberUpdated(object sender, EventArgs e)
        {
            positionSlider.Value = FrameNumber;
            positionTextBlock.Text = FrameNumber.ToString(_numberFormat);
            mainImageContainer.Source = playerModel.CurrentBitmapSource;
        }

        void playerModel_SpeedNumberUpdated(object sender, EventArgs e)
        {
            framesSpeedScrollBar.ValueChanged -= framesSpeedScrollBar_ValueChanged;
            framesTextBox.TextChanged -= framesTextBox_TextChanged;
            framesSpeedScrollBar.Value = playerModel.Speed;
            framesTextBox.Text = playerModel.Speed.ToString(_numberFormat);
            framesSpeedScrollBar.ValueChanged += framesSpeedScrollBar_ValueChanged;
            framesTextBox.TextChanged += framesTextBox_TextChanged;
        }

        void playerModel_StoppedPlaying(object sender, EventArgs e)
        {
            playStopBtn.IsChecked = false;
			playStopBtn.Content = pathCont;
            playStopBtn.UpdateLayout();
        }

        void playerModel_StartedPlaying(object sender, EventArgs e)
        {
            playStopBtn.IsChecked = true;
			playStopBtn.Content = rectangleCont;
            playStopBtn.UpdateLayout();
        }

        void playerModel_MaxTimeUpdated(object sender, EventArgs e)
        {
            positionSlider.Maximum = playerModel.MaxTimeValue;
        }

        #endregion

        private void UserControl_Loaded(object sender, RoutedEventArgs e)
        {
            SetEventHandlers();
        }

        private void SetEventHandlers()
        {
            playerModel.SpeedNumberUpdated += playerModel_SpeedNumberUpdated;
            playerModel.FrameNumberUpdated += playerModel_FrameNumberUpdated;
            playerModel.StartedPlaying += playerModel_StartedPlaying;
            playerModel.StoppedPlaying += playerModel_StoppedPlaying;
            playerModel.MaxTimeUpdated += playerModel_MaxTimeUpdated;
        }
    }
}
